#include "mcf8316a.h"

I2C_BUS mcf8316_i2c;
#define INTERBYTE_DELAY                 2500

#define MCFH &mcf8316_i2c
#define MCF_SEND  mcf8316_i2c.txByte
#define MCF_READ  mcf8316_i2c.rxByte
#define MCF_WAIT  mcf8316_i2c.waitack
#define MCF_STOP  mcf8316_i2c.stop
AT32F415GPIO mcf_sda_out={
    .port = GPIOA,
    .crm_clk_type = CRM_GPIOA_PERIPH_CLOCK,
    .gpio_init_struct ={
        .gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER,
        .gpio_out_type  = GPIO_OUTPUT_OPEN_DRAIN,
        .gpio_mode = GPIO_MODE_OUTPUT,
        .gpio_pins = GPIO_PINS_1,
        .gpio_pull = GPIO_PULL_NONE,
    }
};

AT32F415GPIO mcf_sda_in={
    .port = GPIOA,
    .crm_clk_type = CRM_GPIOA_PERIPH_CLOCK,
    .gpio_init_struct ={
        .gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER,
        .gpio_out_type  = GPIO_OUTPUT_OPEN_DRAIN,
        .gpio_mode = GPIO_MODE_INPUT,
        .gpio_pins = GPIO_PINS_1,
        .gpio_pull = GPIO_PULL_NONE,
    }
};

AT32F415GPIO mcf_scl={
    .port = GPIOA,
    .crm_clk_type = CRM_GPIOA_PERIPH_CLOCK,
    .gpio_init_struct ={
        .gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER,
        .gpio_out_type  = GPIO_OUTPUT_OPEN_DRAIN,
        .gpio_mode = GPIO_MODE_OUTPUT,
        .gpio_pins = GPIO_PINS_1,
        .gpio_pull = GPIO_PULL_NONE,
    }
};
#ifndef BRUSH_FAN
void app_fan_init(void)
{
    i2c_bus_init(&mcf8316_i2c,&mcf_sda_out,&mcf_sda_in,&mcf_scl);
	debug("fan init\n");
}
#endif
void mcf_delay(uint32_t cnt)
{
    while(cnt--);
}
bool mcf_write32(uint32_t addr, uint64_t data)
{
    MCFCONTROLWDU mcf_control_word;
    mcf_control_word.mcfctrwd.mem_addr = addr;
    mcf_control_word.mcfctrwd.mem_page = 0;
    mcf_control_word.mcfctrwd.mem_sec = 0;
    mcf_control_word.mcfctrwd.dlen = 1;//32bit
    mcf_control_word.mcfctrwd.rw = 0;//wrtie
    if(mcf8316_i2c.start(&mcf8316_i2c)==0)
    {
        return FALSE;
    }
    MCF_SEND(MCFH,(MCF_DEV_ID<<1)&0xFE);
    if(!mcf8316_i2c.waitack(&mcf8316_i2c))
    {
        mcf8316_i2c.stop(&mcf8316_i2c);
        return FALSE;
    }
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(MCFH,mcf_control_word.data[2]);
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(&mcf8316_i2c,mcf_control_word.data[1]);
    MCF_WAIT(&mcf8316_i2c);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(&mcf8316_i2c,mcf_control_word.data[0]);
    MCF_WAIT(&mcf8316_i2c);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(MCFH,data&0xFF);
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(MCFH,(data>>8)&0xFF);
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(MCFH,(data>>16)&0xFF);
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(MCFH,(data>>24)&0xFF);
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_STOP(MCFH);
}
bool mcf_read32(uint32_t addr, uint32_t *data)
{
    unsigned char val;
	uint32_t r = 0;
    MCFCONTROLWDU mcf_control_word;
    mcf_control_word.mcfctrwd.mem_addr = addr;
    mcf_control_word.mcfctrwd.mem_page = 0;
    mcf_control_word.mcfctrwd.mem_sec = 0;
    mcf_control_word.mcfctrwd.dlen = 1;
    mcf_control_word.mcfctrwd.rw = 1;
    if(mcf8316_i2c.start(&mcf8316_i2c)==0)
    {
        return FALSE;
    }
    MCF_SEND(MCFH,(MCF_DEV_ID<<1)&0xFE);
    if(!mcf8316_i2c.waitack(&mcf8316_i2c))
    {
        mcf8316_i2c.stop(&mcf8316_i2c);
        return FALSE;
    }
    MCF_SEND(MCFH,mcf_control_word.data[2]);
    MCF_WAIT(&mcf8316_i2c);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(&mcf8316_i2c,mcf_control_word.data[1]);
    MCF_WAIT(&mcf8316_i2c);
    mcf_delay(INTERBYTE_DELAY);
    MCF_SEND(&mcf8316_i2c,mcf_control_word.data[0]);
    MCF_WAIT(&mcf8316_i2c);
    mcf_delay(INTERBYTE_DELAY);
    
    if(mcf8316_i2c.start(&mcf8316_i2c)==0)
    {
        return FALSE;
    }
    MCF_SEND(MCFH,(MCF_DEV_ID<<1)&0xFE);
    MCF_WAIT(&mcf8316_i2c);
    val = MCF_READ(MCFH);
    r|= val;
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    val = MCF_READ(MCFH);
    r|= ((uint32_t)val)<<8;
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    val = MCF_READ(MCFH);
    r|= ((uint32_t)val)<<16;
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    val = MCF_READ(MCFH);
    r|= ((uint32_t)val)<<24;
    MCF_WAIT(MCFH);
    mcf_delay(INTERBYTE_DELAY);
    MCF_STOP(MCFH);
    *data = r;
    return TRUE;
}
